<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>数据精度问题</title>
</head>
<body>
<!-- 
1. 产生精度问题原因
    js中浮点数的计算会有精度不准的问题，比如 0.1 + 0.2 ，应该等于 0.3，
    但实际等于 0.30000000000000004。
    这是因为计算机在计算的过程中，会把十进制数字先转换成二进制，
    因为浮点类型的小数位的限制而截断了计算完的二进制，
    这时候再把它转换为十进制就产生了精度问题。

    举个例子： 0.1 + 0.2 = ?
    0.1 转换成二进制：0.000110011001100110....
    0.2 转换成二进制：0.001100110011001100....
    0.000110011001100110.... + 0.001100110011001100.... = 0.0100110011001100110011001100110011001100110011001100...还很多，如果超过了 52 位就截断了。
    然后转换成十进制：0.30000000000000004

2. 解决：
    （1）toFixed(), 四舍五入，这种方式也是经不起考验的，在不知道数字的情况下，不知道取几位小数才是对的
    （2）彻底消除运算过程中精度问题
        * 先将数字 * 10的n次方，n是小数位数，目的为了将数字转化为整型再计算，    
        * 计算完毕后将计算的最终结果 除以 10的n次方，再转回来。
 -->
</body>
<script type="text/javascript">
    var a = 0.1
    var b = 0.2
    console.log(a+b) // 0.30000000000000004
    var aF = a * Math.pow(10, 1)
    var bF = b * Math.pow(10, 1)
    var res = (aF + bF) / Math.pow(10, 1)
    console.log(res) // 0.3

    
    function add(num1, num2) {
        var p1 = 0;
        var p2 = 0;

        if (num1.toString().split('.').length > 1) {
            p1 = num1.toString().split('.')[1].length;
        }

        if (num2.toString().split('.').length > 1) {
            p2 = num2.toString().split(".")[1].length;
        }

        var p = p1 > p2 ? p1 : p2;

        var n1 = num1 * Math.pow(10, p);
        var n2 = num2 * Math.pow(10, p);

        var result = (n1 + n2) / Math.pow(10, p);

        return result;
    }
    console.log(add(0.1, 0.2)) 


    /*
        通常的处理是：
            将数值 * 10的n次方，n是小数位数，为了升位
            再相加，
            然后拿相加结果 除以 10的n次方，降位回来。
    */

</script>
</html>